package com.fhz.a2102shopjava.ui.login.ui.login;

import android.app.Activity;

import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;

import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;

import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.fhz.a2102shopjava.R;
import com.fhz.a2102shopjava.callback.ApiResponse;
import com.fhz.a2102shopjava.dao.UserDao;
import com.fhz.a2102shopjava.databinding.ActivityLoginBinding;
import com.fhz.a2102shopjava.ui.login.data.model.LoggedInUser;
import com.fhz.a2102shopjava.util.ImageLoader;
import com.fhz.a2102shopjava.util.MyRunnable;
import com.tencent.mmkv.MMKV;

import java.util.concurrent.ExecutorService;

import javax.inject.Inject;

import dagger.hilt.android.AndroidEntryPoint;


@AndroidEntryPoint
public class LoginActivity extends AppCompatActivity {

    private static final String TAG = "LoginActivity";
    @Inject
    UserDao mUserDao;

    @Inject
    ExecutorService mExecutorService;

    private LoginViewModel loginViewModel;
    private ActivityLoginBinding binding;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityLoginBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        loginViewModel = new ViewModelProvider(this).get(LoginViewModel.class);

        final EditText usernameEditText = binding.username;
        final EditText passwordEditText = binding.password;
        final Button loginButton = binding.login;
        final Button registerButton = binding.register;
        final ProgressBar loadingProgressBar = binding.loading;

        ImageLoader.loadCircleDrawable(this,R.drawable.kawayi,binding.avatar);
        loginViewModel.getLoginFormState().observe(this, new Observer<LoginFormState>() {
            @Override
            public void onChanged(@Nullable LoginFormState loginFormState) {
                if (loginFormState == null) {
                    return;
                }
                loginButton.setEnabled(loginFormState.isDataValid());
                if(loginFormState.isDataValid()){
                    registerButton.setEnabled(true);
                }
                if (loginFormState.getUsernameError() != null) {
                    usernameEditText.setError(getString(loginFormState.getUsernameError()));
                }
                if (loginFormState.getPasswordError() != null) {
                    passwordEditText.setError(getString(loginFormState.getPasswordError()));
                }
            }
        });

        loginViewModel.getLoginResult().observe(this, new Observer<LoginResult>() {
            @Override
            public void onChanged(@Nullable LoginResult loginResult) {
                if (loginResult == null) {
                    return;
                }
                loadingProgressBar.setVisibility(View.GONE);
                if (loginResult.getError() != null) {
                    showLoginFailed(loginResult.getError());
                }
                if (loginResult.getSuccess() != null) {
                    updateUiWithUser(loginResult.getSuccess());
                }
                setResult(Activity.RESULT_OK);

                //Complete and destroy login activity once successful
                finish();
            }
        });

        TextWatcher afterTextChangedListener = new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                // ignore
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                // ignore
            }

            @Override
            public void afterTextChanged(Editable s) {
                loginViewModel.loginDataChanged(usernameEditText.getText().toString(),
                        passwordEditText.getText().toString());
            }
        };
        usernameEditText.addTextChangedListener(afterTextChangedListener);
        passwordEditText.addTextChangedListener(afterTextChangedListener);
        passwordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {

            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    loginViewModel.login(usernameEditText.getText().toString(),
                            passwordEditText.getText().toString());
                }
                return false;
            }
        });

        registerButton.setOnClickListener(v -> {
            loadingProgressBar.setVisibility(View.VISIBLE);
            LoggedInUser user = new LoggedInUser();
            user.setNickname(usernameEditText.getText().toString());
            user.setPassword(passwordEditText.getText().toString());
            loginViewModel.register(user).observe(this, new Observer<ApiResponse<LoggedInUser>>() {
                @Override
                public void onChanged(ApiResponse<LoggedInUser> loggedInUserApiResponse) {
                    Toast.makeText(LoginActivity.this, loggedInUserApiResponse.msg, Toast.LENGTH_SHORT).show();
                    loginViewModel.loginResult.setValue(new LoginResult(new LoggedInUserView(loggedInUserApiResponse.data.getNickname())));
                }
            });
        });



        loginButton.setOnClickListener(v -> {
            loadingProgressBar.setVisibility(View.VISIBLE);
            loginViewModel.login(usernameEditText.getText().toString(),
                    passwordEditText.getText().toString()).observe(this, loggedInUserApiResponse -> {
                        //登录成功
                        loginViewModel.loginResult.setValue(new LoginResult(new LoggedInUserView(loggedInUserApiResponse.data.getNickname())));

                        //使用mmkv 保存用户数据及token
                        MMKV mmkv = MMKV.defaultMMKV();
                        mmkv.encode("username",loggedInUserApiResponse.data.getNickname());
                        mmkv.encode("headImage",loggedInUserApiResponse.data.getHeadImage());
                        mmkv.encode("userId",loggedInUserApiResponse.data.getUserId());
                        mmkv.encode("token",loggedInUserApiResponse.msg);

                        MyRunnable myRunnable = new MyRunnable("dao") {
                            @Override
                            public void execute() {
                                //用户登录数据,存入到数据库中.
                                //先判断数据有没有,有就更新,没有就插入
                                LoggedInUser userByName = mUserDao.getUserByName(loggedInUserApiResponse.data.getNickname());
                                if(userByName == null){
                                    mUserDao.insertAll(loggedInUserApiResponse.getData());
                                    Log.i(TAG, "插入用户: "+loggedInUserApiResponse.getData().toString());
                                }else{
                                    mUserDao.updateUser(loggedInUserApiResponse.getData());
                                    Log.i(TAG, "更新用户: ".concat(loggedInUserApiResponse.getData().toString()));
                                }
                            }
                        };
                        mExecutorService.execute(myRunnable);
            });
        });
    }

    private void updateUiWithUser(LoggedInUserView model) {
        String welcome = getString(R.string.welcome) + model.getDisplayName();
        Toast.makeText(getApplicationContext(), welcome, Toast.LENGTH_LONG).show();
    }

    private void showLoginFailed(@StringRes Integer errorString) {
        Toast.makeText(getApplicationContext(), errorString, Toast.LENGTH_SHORT).show();
    }


    public static void launch(Context context){
        Intent intent = new Intent(context, LoginActivity.class);
        context.startActivity(intent);
    }


}